{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Itérer sur une séquence\n",
    "\n",
    "Nous avons présentés précédement les n-uplets, les chaines et les ranges. Nous allons maintenant voir comment manipuler les éléments contenus à l’interieur. Pour cela, nous devons introduire la boucle “pour chaque”.\n",
    "La boucle for\n",
    "\n",
    "La boucle “pour chaque” permet d’exécuter un ensemble d’instructions pour chaque élément contenu dans une séquence. L’exemple suivant nous montre comment afficher les voyelles contenue dans une chaine."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```{code}\n",
    "chaine = input()\n",
    "for c in chaine :\n",
    "    if c in \"aeiouyAEIOUY\" :\n",
    "        print( c )\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "La boucle est composée d’une déclaration `for c in chaine :` et d’un bloc de code. Son fonctionnement est le suivant. Chaque caractère de la sequence `chaine` est associé successivement dans la variable `c`. Pour chaque valeur, les instructions du bloc de code sont exécutées.\n",
    "\n",
    "De manière générale, voici la syntaxe d’une boucle `for`.\n",
    "```\n",
    "for variable in sequence :\n",
    "    instructions\n",
    "    ...\n",
    "    ...\n",
    "```\n",
    "Les boucles `for` peuvent être utilisées avec n’importe quelle séquence ou générateur dont : `str`, `tuple` et `range`. Voici un exemple sur un tuple."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "t = (\"Janvier\", \"Fevrier\", \"Mars\", \"Avril\", \"Mai\", \"Juin\", \"Juillet\", \"Aout\", \"Septembre\", \"Octobre\", \"Novembre\", \"Decembre\")\n",
    "for i in t :\n",
    "    print( i )\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Et un autre exemple sur un `range`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "for i in range(2,10,2):\n",
    "    print( i**2 )\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exercices\n",
    "\n",
    "Nous allons mettre en oeuvre l’utilisation de boucle \"pour chaque\".\n",
    "\n",
    "\n",
    "**Question** : Nous souhaitons faire une fonction qui calcule la somme des éléments contenu dans une séquence. Écrire une fonction `add` qui prend en entrée une séquence de nombres et renvoie la somme des éléments. Tester votre fonction sur une séquence `(2, 3, 6, 0.6, 12, -3.3)`. Attention, il faut donc deux paranthèses. Une pour l'appel de la fonction et une autre pour la séquence."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "20.3"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def add(s):\n",
    "    pass\n",
    "\n",
    "add( (2, 3, 6, 0.6, 12, -3.3) )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Voici une correction possible.\n",
    "\n",
    "```{toggle} Correction.\n",
    "\n",
    "```{code}\n",
    "def add(s):\n",
    "    t = 0\n",
    "    for i in s:\n",
    "        t += i\n",
    "    return t  \n",
    "```\n",
    "\n",
    "En pratique, Python dispose d'une fonction `sum` qui permet de sommer les éléments d'une séquence. On préfèrera faire `sum( (2, 3, 6, 0.6, 12, -3.3) )`."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question** : Faites une fonction `mean`qui prend en paramètre une séquence et renvoie la valeur moyenne des termes de la séquences. Testez votre fonction sur la même séquence."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3.3833333333333333"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def mean(s):\n",
    "    pass\n",
    "\n",
    "mean( (2, 3, 6, 0.6, 12, -3.3) )"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Voici une correction possible.\n",
    "\n",
    "```{toggle} Correction.\n",
    "\n",
    "```{code}\n",
    "def mean(s):\n",
    "    return sum(s) / len(s)  \n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question** : Écrivez une fonction `invert` qui prend en paramètre une chaine de caractères et renvoie une nouvelle chaine à l'envers. `Bonjour` donnera `ruojnoB`.\n",
    "\n",
    "De manière générale, pour **aborder un problème algorithmique**, il est souvent plus simple de **décomposer en étapes simples**. Dans notre cas, il peut être intéressant de commencer par afficher chaque lettre d'une chaine de caractère en commençant du début. Puis en partant de la fin. Et enfin d'accumuler les lettres dans une nouvelle chaine de caractères. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "def invert(c):\n",
    "    pass\n",
    "        \n",
    "invert(\"Bonjour\")  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Correction de la première étape\n",
    "\n",
    "```{toggle} Correction.\n",
    "\n",
    "```{code}\n",
    "# Affichage des lettres dans l'ordre\n",
    "def invert(c):\n",
    "    for i in range(len(c)):\n",
    "        print(c[i])\n",
    "        \n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Correction de la deuxième étape\n",
    "\n",
    "```{toggle} Correction.\n",
    "\n",
    "```{code}\n",
    "# Affichage des lettres dans l'ordre inverse on part de -1 \n",
    "def invert(c):\n",
    "    for i in range(len(c)):\n",
    "        print(c[-1-i])\n",
    "        \n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Correction de l'étape finale.\n",
    "\n",
    "```{toggle} Correction.\n",
    "\n",
    "```{code}\n",
    "# On accumule les lettres dans une chaine de caractères on l'a renvoie à la fin.\n",
    "def invert(c):\n",
    "    n = \"\"\n",
    "    for i in range(len(c)):\n",
    "        n += c[-1-i]\n",
    "    return n\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question** : Faites une fonction `is_palindrome` qui prend en paramètre une chaine de caractère et renvoie `True` ou `False`. Un palindrome est un mot qui se lit de la même façon dans les deux sens : kayak, radar.\n",
    "\n",
    "**Indice** :\n",
    "- Avec `range` vous pouvez parcourir une chaine de caractères dans un sens et dans l'autre en même temps.\n",
    "- Rappelez vous que le mot clef `return` arrête l'exécution d'une fonction (même si on est dans une boucle)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Besoin d'un indice en plus ? Voici un algorithme qui fonctionne.\n",
    "\n",
    "```{toggle} Correction.\n",
    "On parcours la chaine dans les deux sens à la fois. Dès que l'on trouve une erreur, on s'arrête, on renvoie `False`. Si après avoir parcouru tous les indices, on n'a pas rencontré d'erreur, on renvoie `True`.\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "def is_palindrome( c ):\n",
    "    pass\n",
    "    \n",
    "is_palindrome(\"ressasser\")\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Voici une correction possible.\n",
    "\n",
    "```{toggle} Correction.\n",
    "\n",
    "```{code}\n",
    "def is_palindrome( c ):\n",
    "    for i in range(len(c)):\n",
    "        if c[i] != c[-1-i]:\n",
    "            return False\n",
    "    return True \n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question** : Sans testez, d'après vous, est-ce que votre fonction `is_palindrome` fonctionne si on lui donne en entrée une séquence de nombres ?\n",
    "\n",
    "```\n",
    "is_palindrome((2, 3, 6, 0.6, 12, -3.3))\n",
    "```\n",
    "\n",
    "Vérifiez votre réponse, elle pourrait varier selon la manière dont vous avez traiter la question."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "```{toggle} Correction.\n",
    "Votre fonction devrait fonctionner. En tout cas si vous avez fait quelque chose de similaire au corrigé. C'est normal car les chaines de caractères et les tuples fonctionnent de manière très similaire.\n",
    "\n",
    "En Python, on ne demande pas que le paramètre d'une fonction soit d'un type en particulier, mais à l'exécution il faudra que toutes les oppérations fonctionnent sans erreur.\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question** : On veut maintenant tester également des chaines de caractères contenant des majuscules. Vous pouvez utiliser la fonction `upper` qui permet de renvoyer une chaine de caractères tout en majuscule. Exemple `\"Une Chaine\".upper()` renvoie la valeur `UNE CHAINE`. Il existe aussi `lower`.\n",
    "\n",
    "Faites une fonction `is_palindrome2` pour ce cas là."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Voici une correction possible.\n",
    "\n",
    "```{toggle} Correction.\n",
    "\n",
    "```{code}\n",
    "def is_palindrome2( c ):\n",
    "    return is_palindrome( c.upper() )\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Question** : Que se passe-t-il si vous utilisez la fonction `is_palindrome2` sur une séquence de nombre ?\n",
    "\n",
    "```\n",
    "is_palindrome2((2, 3, 6, 0.6, 12, -3.3))\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "```{toggle} Correction.\n",
    "Ici, on ne peut plus utiliser notre fonction avec un tuple car la fonction `upper` n'existe pas pour les tupples. C'est quelque chose de spécifique aux chaines de caractères.\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
